﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Printing;
using System.Drawing;
using Dycox.Drawing;
using System.ComponentModel;
using Dycox.Reporting.Printing;

namespace Dycox.Reporting
{
    public class ReportPageSettings
    {
        Report _report;

        internal ReportPageSettings(Report report)
        {
            if (report == null)
                throw new ArgumentNullException("report");

            _report = report;
        }

        private ReportPageUnit _unit;

        public ReportPageUnit Unit
        {
            get { return _unit; }
            set { _unit = value; }
        }

        private SizeF _paperSize;

        public SizeF PaperSize
        {
            get { return _paperSize; }
            set
            {
                _paperSize = value;
                UpdateBodyBounds();
            }
        }

        public SizeF PaperSizeMM
        {
            get
            {
                SizeF size = _paperSize;
                switch (_unit)
                {
                    case ReportPageUnit.Millimeter:
                        return size;
                    case ReportPageUnit.Centimeter:
                        return new SizeF(size.Width * 10f, size.Height * 10f);
                    default:
                        throw new NotSupportedException("Unit " + _unit + " is not supported yet.");
                }
            }
        }

        private string _paperName;

        public string PaperName
        {
            get { return _paperName; }
            set { _paperName = value; }
        }


        private bool _landscape;

        public bool Landscape
        {
            get { return _landscape; }
            set
            {
                _landscape = value;
                UpdateBodyBounds();
            }
        }

        private void UpdateBodyBounds()
        {
            //ReportBody body = _report.Body;
            //body.Bounds = GetBounds(true);
            //throw new NotImplementedException();
        }

        private RectangleF GetBounds(bool margins)
        {
            RectangleF bounds = new RectangleF(PointF.Empty, _paperSize);

            if (margins)
            {
                bounds.X += _margins.Left;
                bounds.Y += _margins.Top;
                bounds.Width -= _margins.Left + _margins.Right;
                bounds.Height -= _margins.Top + _margins.Bottom;
            }

            if (_landscape)
            {
                float tmp = bounds.Width;
                bounds.Width = bounds.Height;
                bounds.Height = tmp;
            }

            return bounds;
        }

        public RectangleF GetPaperBounds()
        {
            return GetBounds(false);
        }

        private Paddings _margins;

        public Paddings Margins
        {
            get { return _margins; }
            set
            {
                _margins = value;
                UpdateBodyBounds();
            }
        }

        private int _columns = 1;

        [DefaultValue(1)]
        public int Columns
        {
            get { return _columns; }
            set
            {
                if (value < 1)
                    throw new ArgumentOutOfRangeException();

                _columns = value;
            }
        }

        private int _rows;

        public int Rows
        {
            get { return _rows; }
            set
            {
                if (value < 0)
                    throw new ArgumentOutOfRangeException();

                _rows = value;
            }
        }

        private OverflowHandling _verticalOverflow;

        public OverflowHandling VerticalOverflow
        {
            get { return _verticalOverflow; }
            set { _verticalOverflow = value; }
        }

        private OverflowHandling _horizontalOverflow;

        public OverflowHandling HorizontalOverflow
        {
            get { return _horizontalOverflow; }
            set { _horizontalOverflow = value; }
        }

        private PageBreakMode _pageBreak;

        public PageBreakMode PageBreak
        {
            get { return _pageBreak; }
            set { _pageBreak = value; }
        }

        private float _horizontalSpace;

        public float HorizontalSpace
        {
            get { return _horizontalSpace; }
            set { _horizontalSpace = value; }
        }

        private float _verticalSpace;

        public float VerticalSpace
        {
            get { return _verticalSpace; }
            set { _verticalSpace = value; }
        }

        internal Margins CreatePrintingMargins()
        {
            float factor = 10;
            if (_unit == ReportPageUnit.Centimeter) factor *= 10;

            float left = _margins.Left * factor,
                top = _margins.Top * factor,
                right = _margins.Right * factor,
                bottom = _margins.Bottom * factor;

            return new System.Drawing.Printing.Margins(
                (int)(PrinterUnitConvert.Convert(left, PrinterUnit.TenthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch) / 10),
                (int)(PrinterUnitConvert.Convert(right, PrinterUnit.TenthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch) / 10),
                (int)(PrinterUnitConvert.Convert(top, PrinterUnit.TenthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch) / 10),
                (int)(PrinterUnitConvert.Convert(bottom, PrinterUnit.TenthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch) / 10));

        }
    }
}
